home *** CD-ROM | disk | FTP | other *** search
- /*
- linfit(XYpoints)
- Fit data to a straight line using linear regression formula.
- */
-
- /* This file uses the "globals" version of callbacks. It handles setup of A4.
- The linfit() function does not actually need globals so it can be implemented
- without A4 setup. See "linfit68K.c" */
-
- #include "A4globs.h" /* magic A4 macros */
- #include "callbackg.h" /* use "global" version of callbacks */
-
- #include <fp.h> /* needed for sqrt() */
- short errno; /* needed for sqrt() */
-
- funptr callback; /* required for "callbackg.c" */
-
-
- static short linfit(double *retval)
- {
- EXPR arr;
- double x,y,*iptr,*jptr,intercept;
- double sumx,sumxx,sumy,sumyy,sumxy,Sxx,Sxy;
- short isarray;
- long n,count;
-
- sumx=0; sumxx=0; sumy=0; sumyy=0; sumxy=0;
- n = 0;
- MakeParmExpr(0,&arr);
- ProbeExpr(arr,&x,&isarray,&count);
- if(!isarray || count<2)
- {
- ErrMsg(" linfit() expects array of {x,y}",0L);
- FreeExpr(arr);
- return(FALSE);
- }
- AddIndex(&arr,&iptr); // arr[i] is {x,y}
- AddIndex(&arr,&jptr); // j picks x or y
- while(count--)
- {
- *jptr = 1;
- if(EvalExpr(arr,&x) && x==x)
- {
- *jptr = 2;
- if(EvalExpr(arr,&y) && y==y)
- {
- sumx += x;
- sumxx += x*x;
- sumy += y;
- sumyy += y*y;
- sumxy += x*y;
- n++;
- }
- }
- *iptr += 1;
- }
- Sxx=n*sumxx-sumx*sumx;
- Sxy=n*sumxy-sumx*sumy;
-
- SetVarVal("slope",Sxy/Sxx);
- intercept=(sumxx*sumy-sumx*sumxy)/(n*sumxx-sumx*sumx);
- SetVarVal("intercept",intercept);
- *retval = Sxy/sqrt(Sxx*(n*sumyy-sumy*sumy)); // return correlation coeff
-
- FreeExpr(arr);
- return(TRUE);
- }
-
- /* -------- entry points handle A4 setup & restore ------------*/
-
- static short funcall(double *retval,funptr callbackptr)
- {
- int ok;
- SetUpA4();
- ok = linfit(retval);
- RestoreA4();
- return(ok);
- }
-
- void main(funptr callbackptr)
- {
- EnterResource();
- callback = callbackptr; /* save callback in global for callbackg routines */
- AddXfun("linfit","XYpoints",&funcall,NULL);
- RestoreA4();
- }
-